package pl.enigmatic.objects;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;


public class WrapperObject<B> {

	public static <B, W extends WrapperObject<B>> B base(final W wrapper) {
		return wrapper != null ? wrapper.getBase() : null;
	}

	public static <B, W extends WrapperObject<B>, S extends Set<B>> S base(final Set<W> from, final S to) {
		for (final W w : from) {
			to.add(base(w));
		}
		return to;
	}

	public static <B, W extends WrapperObject<B>> Set<B> base(final Set<W> set) {
		return base(set, new HashSet<B>());
	}

	public static <B, W extends WrapperObject<B>, L extends List<B>> L base(final List<W> from, final L to) {
		for (final W w : from) {
			to.add(base(w));
		}
		return to;
	}

	public static <B, W extends WrapperObject<B>> List<B> base(final List<W> list) {
		return base(list, new Vector<B>());
	}

	public static <B, W extends WrapperObject<B>, K, M extends Map<K, B>> M baseVal(final Map<K, W> from, final M to) {
		for (final Entry<K, W> e : from.entrySet()) {
			to.put(e.getKey(), base(e.getValue()));
		}
		return to;
	}

	public static <B, W extends WrapperObject<B>, K, M extends Map<K, B>> Map<K, B> baseVal(final Map<K, W> map) {
		return baseVal(map, new HashMap<K, B>());
	}

	public static <B, W extends WrapperObject<B>, V, M extends Map<B, V>> M baseKey(final Map<W, V> from, final M to) {
		for (final Entry<W, V> e : from.entrySet()) {
			to.put(base(e.getKey()), e.getValue());
		}
		return to;
	}

	public static <B, W extends WrapperObject<B>, V, M extends Map<B, V>> Map<B, V> baseKey(final Map<W, V> map) {
		return baseKey(map, new HashMap<B, V>());
	}

	private final B base;

	public WrapperObject(final B base) {
		this.base = base;
	}

	/**
	 * @return the base
	 */
	public B getBase() {
		return base;
	}
}
